package org.funtester.performance.books.chapter04.section4;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.Header;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.message.BasicHeader;
import org.funtester.performance.books.chapter04.section2.HttpRequestTool;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 自定义日志格式,用于记录请求信息,并实现Delayed接口,用于延迟队列
 */
public class FunLog implements Delayed {

    private static final Header TYPE = new BasicHeader("type", "FunTesterReplay");

    /**
     * 请求地址,对于GET请求来说包含参数
     */
    public String uri;

    /**
     * 请求方法,仅支持GET或POST
     */
    public String method;

    /**
     * 请求参数,对于POST请求来说包含参数
     */
    public JSONObject params;

    /**
     * 请求到期时间戳,单位毫秒
     */
    public long timestamp;

    /**
     * 这里我们使用逗号分隔的字符串来初始化对象
     * @param logLine
     */
    public FunLog(String logLine) {
        String[] log = logLine.split(",");
        this.uri = log[0];
        this.method = log[1];
        this.params = JSONObject.parseObject(log[2]);
        this.timestamp = Long.parseLong(log[3]);
    }

    /**
     * 将funlog转化成httprequest对象
     * @param token 用户登录凭证
     * @param data  请求参数，用以覆盖funlog中的参数
     * @return
     */
    public HttpRequestBase toRequest(String host, String token, JSONObject data) {
        HttpRequestBase request = null;
        if (params != null && data != null) {// 如果请求参数不为空,则合并参数,以data为准覆盖params
            params.putAll(data);
        }
        if (method.equalsIgnoreCase("get")) {
            request = HttpRequestTool.getHttpGet(host + uri, params);
        } else if (method.equalsIgnoreCase("post")) {
            request = HttpRequestTool.getHttpPost(host + uri, data);
        } else {
            throw new RuntimeException("不支持的请求方法");
        }
        request.addHeader("token", token);
        request.addHeader(TYPE);
        return request;
    }

    /**
     * 获取延迟时间,单位毫秒,超过到期时间则能被取出
     * @param unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return this.timestamp - System.currentTimeMillis();
    }

    /**
     * 比较方法,用于排序,按照到期时间升序排列
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        return (int) (this.timestamp - ((FunLog) o).timestamp);
    }

}
